﻿using System;
using System.Collections;
using System.Configuration;
using System.Reflection;
using System.Xml;
using AiFrame.InterfaceLib.Logs;

namespace AiFrame.InterfaceLib.Configuration
{
    /// <summary>
    /// Loads configuration settings for a specific
    /// assembly.
    /// </summary>
    public class AssemblySettings
    {
        /// <summary>
        /// The settings.
        /// </summary>
        private IDictionary settings;

        /// <summary>
        /// This constructor is for loading and saving settings
        /// for the current assembly.
        /// </summary>
        public AssemblySettings()
            : this(Assembly.GetCallingAssembly())
        {
        }

        /// <summary>
        /// This constructor is for loading and saving settings
        /// for a foreign assembly.
        /// </summary>
        /// <param name="asm"></param>
        public AssemblySettings(Assembly asm)
        {
            settings = GetConfig(asm);
        }

        /// <summary>
        /// Gets settings for a specific key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>The value for the key.</returns>
        public string this[string key]
        {
            get
            {
                string settingValue = null;

                if (settings != null)
                {
                    settingValue = settings[key] as string;
                }

                return (settingValue == null ? "" : settingValue);
            }
        }

        /// <summary>
        /// Gets the settings dictionary of the calling assembly.
        /// </summary>
        /// <returns>The dictionary.</returns>
        public static System.Collections.IDictionary GetConfig()
        {
            return GetConfig(Assembly.GetCallingAssembly());
        }

        /// <summary>
        /// Gets the settings dictionary of a specific assembly.
        /// </summary>
        /// <param name="asm">The assembly.</param>
        /// <returns>The dictionary.</returns>
        public static System.Collections.IDictionary GetConfig(Assembly asm)
        {
            // Open and parse configuration file for specified
            // assembly, returning collection to caller for future
            // use outside of this class.            
            try
            {
                string cfgFile = asm.CodeBase + ".config";
                const string nodeName = "assemblySettings";

                XmlDocument doc = new XmlDocument();
                doc.Load(new XmlTextReader(cfgFile));

                XmlNodeList nodes = doc.GetElementsByTagName(nodeName);

                foreach (XmlNode node in nodes)
                {
                    if (node.LocalName == nodeName)
                    {
                        DictionarySectionHandler handler = new DictionarySectionHandler();
                        return (System.Collections.IDictionary)handler.Create(null, null, node);
                    }
                }
            }
            catch (Exception e)
            {
                LogHandler.GetLogger().Error("Could not open configuration file: ", e);
                System.Diagnostics.Debug.WriteLine(e.Message);
            }

            return (null);
        }
    }
}